package com.macllvm.whale.model;

import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.content.Context;
import java.nio.channels.SocketChannel;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.FutureTask;
import java.util.Observable;
import java.util.concurrent.atomic.AtomicInteger;
import com.macllvm.whale.entity.Transfer;
import com.macllvm.whale.net.TCPFileRecvTask;


public class TransferInManager  extends  Observable implements IProgressCallback{
    private LinkedList<Transfer> transferList = new LinkedList<Transfer>();
    private LinkedList<FutureTask<Integer>> recvTaskList = new LinkedList<FutureTask<Integer>>();
    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private ExecutorService  executorService;
    private AtomicInteger fileId = new AtomicInteger(10000);

    public TransferInManager() {
        executorService = Executors.newSingleThreadExecutor();
    }

    public void add(Transfer t){

        Lock l = lock.writeLock();
        l.lock();
        try{
            t.index = transferList.size();
            TCPFileRecvTask task = new TCPFileRecvTask(t, this);
            FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
            transferList.add(t);
            recvTaskList.add(futureTask);
            executorService.submit(futureTask);
            this.setChanged();
            this.notifyObservers();

        }finally {
            l.unlock();
        }
    }

    public Transfer getTansferById(int Id){
        Lock l = lock.readLock();
        l.lock();
        try{

            Transfer t = null;
            int count = transferList.size();
            if(count == 1){
                return (Transfer)transferList.get(0);
            }

            for(int i =0; i < count; i++){
                t = transferList.get(i);
                if( t.fileId == Id){
                    return t;
                }
            }
            return t;
        }finally {
            l.unlock();
        }
    }

    public void stopTask(int index){
        Lock l = lock.readLock();
        l.lock();
        try{
            if(transferList.get(index).percent < 100 ) {
                recvTaskList.get(index).cancel(true);
                transferList.get(index).state = Transfer.STATE_CANCEL;
            }
            this.setChanged();
            this.notifyObservers(index);
        }finally {
            l.unlock();
        }
    }

    public int getFileSendId() {
        return fileId.addAndGet(1);
    }

    public LinkedList<Transfer> getDataSource() {
        return transferList;
    }

    public LinkedList<FutureTask<Integer>> getTaskList() {
        return recvTaskList;
    }

    public void stopAllTask() {
        executorService.shutdownNow();
    }

    @Override
    public void refreshProgress(int index){
        this.setChanged();
        this.notifyObservers(index);
    }

    @Override
    public Transfer getTransfer(int fileId){
        return getTansferById(fileId);
    }

}
